package com.example.apistroage;


import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.os.storage.StorageManager;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";

    private LinearLayout llContent;
    private TextView tvApi;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.tv_test_permission).setOnClickListener(clickListener);
        initView();

        initData();
    }

    private void initView() {
        llContent = findViewById(R.id.ll_content);
        tvApi = findViewById(R.id.tv_api);
    }

    private void initData() {
        tvApi.setText("API : " + Build.VERSION.SDK_INT);
        String[] paths = getPrimaryStoragePath();
        if (paths == null) {
            return;
        }
        for (int i = 0; i < paths.length; i++) {
            queryStorage(paths[i]);
        }
    }

    private View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.tv_test_permission) {
                testPermission(MainActivity.this);
            }
        }
    };

    private void testPermission(Activity activity) {
        String[] checkList = new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE
        };
        List<String> needRequestList = checkPermission(activity, checkList);
        if (needRequestList.isEmpty()) {
            Toast.makeText(MainActivity.this, "无需申请权限", Toast.LENGTH_SHORT).show();
        } else {
            requestPermission(activity, needRequestList.toArray(new String[needRequestList.size()]));
        }
    }

    private List<String> checkPermission(Context context, String[] checkList) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < checkList.length; i++) {
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(context, checkList[i])) {
                list.add(checkList[i]);
            }
        }
        return list;
    }

    private void requestPermission(Activity activity, String requestPermissionList[]) {
        ActivityCompat.requestPermissions(activity, requestPermissionList, 100);
    }

    public void queryStorage(String path) {
//        StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
        StatFs statFs = new StatFs(path);

        //存储块总数量
        long blockCount = statFs.getBlockCountLong();
        //块大小
        long blockSize = statFs.getBlockSizeLong();
        //可用块数量
        long availableCount = statFs.getAvailableBlocksLong();
        //剩余块数量，注：这个包含保留块（including reserved blocks）即应用无法使用的空间
        long freeBlocks = statFs.getFreeBlocksLong();
        //这两个方法是直接输出总内存和可用空间，也有getFreeBytes
        //API level 18（JELLY_BEAN_MR2）引入
        long totalSize = statFs.getTotalBytes();
        long availableSize = statFs.getAvailableBytes();
        long freeSize = statFs.getFreeBytes();

        SDData data = new SDData();
        data.total = getUnit(totalSize);
        data.available = getUnit(availableSize);
        data.path = path;
        data.freeBlock =getUnit(freeSize);
        data.setAmount(getStorageState(path));

        SDCardHolder sdCardHolder = new SDCardHolder(MainActivity.this);
        sdCardHolder.setData(data);

        llContent.addView(sdCardHolder.getRootView());

        Log.d("statfs", "total = " + getUnit(totalSize));
        Log.d("statfs", "availableSize = " + getUnit(availableSize));

        //这里可以看出 available 是小于 free ,free 包括保留块。
        Log.d("statfs", "total = " + getUnit(blockSize * blockCount));
        Log.d("statfs", "available = " + getUnit(blockSize * availableCount));
        Log.d("statfs", "free = " + getUnit(blockSize * freeBlocks));
    }

    private String[] units = {"B", "KB", "MB", "GB", "TB"};

    /**
     * 单位转换
     */
    private String getUnit(float size) {
        int index = 0;
        while (size > 1024 && index < 4) {
            size = size / 1024;
            index++;
        }
        return String.format(Locale.getDefault(), " %.2f %s", size, units[index]);
    }

    // 获取存储卡路径
    public String[] getPrimaryStoragePath() {
        try {
            StorageManager sm = (StorageManager) getSystemService(STORAGE_SERVICE);
            Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths");
            String[] paths = (String[]) getVolumePathsMethod.invoke(sm);
            // first element in paths[] is primary storage path
            return paths;
        } catch (Exception e) {
            Log.e(TAG, "getPrimaryStoragePath() failed", e);
        }
        return null;
    }

//    // 获取次存储卡路径,一般就是外置 TF 卡了. 不过也有可能是 USB OTG 设备...
//    // 其实只要判断第二张卡在挂载状态,就可以用了.
//    public String getSecondaryStoragePath() {
//        try {
//            StorageManager sm = (StorageManager) getSystemService(STORAGE_SERVICE);
//            Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", null);
//            String[] paths = (String[]) getVolumePathsMethod.invoke(sm, null);
//            // second element in paths[] is secondary storage path
//            return paths.length <= 1 ? null : paths[1];
//        } catch (Exception e) {
//            Log.e(TAG, "getSecondaryStoragePath() failed", e);
//        }
//        return null;
//    }

    // 获取存储卡的挂载状态. path 参数传入上两个方法得到的路径
    public String getStorageState(String path) {
        try {
            StorageManager sm = (StorageManager) getSystemService(STORAGE_SERVICE);
            Method getVolumeStateMethod = StorageManager.class.getMethod("getVolumeState", new Class[]{String.class});
            String state = (String) getVolumeStateMethod.invoke(sm, path);
            return state;
        } catch (Exception e) {
            Log.e(TAG, "getStorageState() failed", e);
        }
        return null;
    }


}